;

#include "messagequeue.h"

MessageQueue* MessageQueue::_instance = nullptr;

MessageQueue::MessageQueue() {
}

MessageQueue::~MessageQueue() {
	_mapMessages.clear();
}

MessageQueue* MessageQueue::getInstance() {
	if(!_instance) {
		_instance = new MessageQueue();
		_instance->init();
	}

	return _instance;
}

void MessageQueue::init() {
	for(int i = 1; i < (int)MessageTarget::count; i++) { // skip 0 - all
		queue<MessageData> q;
		_mapMessages.insert(make_pair((MessageTarget)i, q));
	}
}

void MessageQueue::send(const MessageData& msg) {
	if(msg.receiver == MessageTarget::all) {
		for(auto item : _mapMessages) {
			MessageTarget k = item.first;
			queue<MessageData>& q = _mapMessages[k];
			q.push(msg);
		}

	} else {
		auto it = _mapMessages.find(msg.receiver);
		if(it == _mapMessages.end()) {
			queue<MessageData> q;
			q.push(msg);
			_mapMessages.insert(make_pair(msg.receiver, q));
		} else {
			queue<MessageData>& q = _mapMessages[msg.receiver];
			q.push(msg);
		}
	}
}

MessageData * MessageQueue::peek(MessageTarget receiver) {
	auto it = _mapMessages.find(receiver);
	if(it == _mapMessages.end()) {
		return nullptr;
	} 
	
	queue<MessageData>& q = it->second;
	if(q.empty()) {
		return nullptr;
	}

	return &(q.front());
}

void MessageQueue::pop(MessageTarget receiver) {
	auto it = _mapMessages.find(receiver);
	if(it != _mapMessages.end()) {
		queue<MessageData>& q = it->second;
		if(!q.empty()) {
			q.pop();
		}
	}
}

void MessageQueue::clear(MessageTarget target) {
	if(target == MessageTarget::all) {
		_mapMessages.clear();
		init();
	} else {
		auto it = _mapMessages.find(target);
		if(it != _mapMessages.end()) {
			queue<MessageData>& q = it->second;
			while(!q.empty()) {
				q.pop();
			}
		}
	}
}
